﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Kindohm.Life.Library
{
    public class Carnivore : Creature
    {

        Corpse plannedCorpse;
        Herbivore plannedPrey;
        int kills;

        public static new Carnivore Create()
        {
            Carnivore item = new Carnivore();
            Creature.Initialize(item, true);
            return item;
        }

        public Corpse PlannedCorpse
        {
            get { return this.plannedCorpse; }
        }

        public Herbivore PlannedPrey
        {
            get { return this.plannedPrey; }
        }

        protected override void ProcessFreeWill()
        {
            if (this.plannedMate != null)
            {
                this.GoForMate(this.plannedMate);
                return;
            }

            if (this.plannedPrey != null)
            {
                this.GoForPrey(this.plannedPrey);
                return;
            }

            if (this.plannedCorpse != null)
            {
                this.GoForCorpse(this.plannedCorpse);
                return;
            }

            if (!this.IsHorny & !this.IsHungry)
            {
                //nothin to do
                this.Walk();
                return;
            }

            Creature idealMate = null;

            if (this.IsHorny)
            {
                idealMate = this.FindIdealMate();
            }

            Corpse idealFood = null;
            Herbivore idealPrey = null;

            if (this.IsHungry)
            {
                CorpseFinder finder = new CorpseFinder();
                idealFood = finder.FindIdealCorpse(this.Board, this.Position, this.Sight);

                //if (idealFood == null)
                //{
                    PreyFinder preyFinder = new PreyFinder();
                    idealPrey = preyFinder.FindIdealPrey(this.Board, this.Position, this.Sight);
                //}

            }

            if (idealMate != null & idealFood == null & idealPrey == null)
            {
                this.GoForMate(idealMate);
                return;
            }

            if (idealMate == null & idealFood != null & idealPrey == null)
            {
                this.GoForCorpse(idealFood);
                return;
            }

            if (idealMate == null & idealFood == null & idealPrey != null)
            {
                this.GoForPrey(idealPrey);
                return;
            }

            if (idealMate != null & idealFood != null & idealPrey == null)
            {
                int foodDistance = Point.Distance(this.Position, idealFood.Position);
                int mateDistance = Point.Distance(this.Position, idealMate.Position);

                if (foodDistance <= mateDistance)
                {
                    this.GoForCorpse(idealFood);
                    return;
                }
                else
                {
                    this.GoForMate(idealMate);
                    return;
                }
            }

            if (idealMate != null & idealFood == null & idealPrey != null)
            {
                int preyDistance = Point.Distance(this.Position, idealPrey.Position);
                int mateDistance = Point.Distance(this.Position, idealMate.Position);

                if (preyDistance <= mateDistance)
                {
                    this.GoForPrey(idealPrey);
                    return;
                }
                else
                {
                    this.GoForMate(idealMate);
                    return;
                }
            }

            if (idealMate == null & idealFood != null & idealPrey != null)
            {
                int preyDistance = Point.Distance(this.Position, idealPrey.Position);
                int foodDistance = Point.Distance(this.Position, idealFood.Position);

                if (preyDistance <= foodDistance)
                {
                    this.GoForPrey(idealPrey);
                    return;
                }
                else
                {
                    this.GoForCorpse(idealFood);
                    return;
                }
            }

            //last resort
            this.Walk();

            base.ProcessFreeWill();

        }

        void GoForPrey(Herbivore prey)
        {
            if (prey.IsDead)
            {
                this.plannedPrey = null;
                return;
            }

            if (Board.AreAdjacent(prey.Position, this.Position))
            {
                this.Attack(prey);
                return;
            }
            else
            {
                this.plannedPrey = prey;
                this.WalkTo(prey.Position);
                return;
            }
        }

        void GoForCorpse(Corpse corpse)
        {
            if (corpse.Nutrition == 0)
            {
                this.plannedCorpse = null;
                return;
            }

            if (Board.AreAdjacent(corpse.Position, this.Position))
            {
                this.Eat(corpse);
                return;
            }
            else
            {
                this.plannedCorpse = corpse;
                this.WalkTo(corpse.Position);
                return;
            }
        }

        public int Kills
        {
            get { return this.kills; }
        }

        public override void Eat(IEdible target)
        {
            this.plannedCorpse = null;
            base.Eat(target);
        }

        public void Attack(Creature target)
        {
            this.plannedPrey = null;
            target.Die(CauseOfDeath.Attacked);
            this.kills++;
            this.OnAttack(target);
        }

        protected void OnAttack(Creature prey)
        {
            if (this.Attacking != null)
            {
                AttackEventArgs e = new AttackEventArgs(this, prey);
                this.Attacking(this, e);
            }
        }

        protected override Creature FindIdealMate()
        {
            if (this.Board == null)
            {
                return null;
            }

            MateFinder finder = new MateFinder();
            Sex targetSex = Sex.Male;
            if (this.Sex == Sex.Male)
            {
                targetSex = Sex.Female;
            }
            return finder.FindIdealMate(this.Board, this.Position, this.Sight, targetSex, typeof(Carnivore));
        }

        public event EventHandler<AttackEventArgs> Attacking;

        
    }
}
